package net.helix.ui.panels.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;

import net.helix.core.transform.Transform;
import net.helix.core.transform.TransformDimension;
import net.helix.core.transform.ViewTransform;
import net.helix.element.Element_Camera;
import net.helix.element.ViewNodeElement;
import net.helix.engine.Engine;
import net.helix.engine.timeline.layer.TimelineLayer;
import net.helix.engine.viewPath.ViewNode;
import net.helix.engine.viewPath.ViewPath;
import net.helix.ui.UIImages;
import net.helix.ui.panels.JImageButton;

import org.lwjgl.LWJGLException;

/**
 * The view pane is the main way the user will sample his/her animation. Multiple view panes exist and each
 * view pane can be set to a different position, rotation, and even camera.<br><br>
 * One of the key features of Helix is being able to view each separate camera's view in each view pane and
 * also having the option to view all camera's views at once. There is a drop down menu attached to each view
 * pane that allows the user to select from each camera layer in the current scene. Among those options is
 * the "preview" option which concatenates all views into one.<br><br>
 * An example of how this can be done is the following:<br>
 *  - A 2d camera layer exists in the back for a solid, non-moving background.<br>
 *  - A 3d camera layer for the main components of the animation.
 *  - Another 2d layer in front of everything to display an HUD (could be for dialouges or stamina bars. Maybe even
 *  those black bars at the top and bottom of a movie to give it a "focused" effect like in zelda games...)<br><br>
 *  In the above example, each camera layer can be chosen in a view pane, or the last option to view them all at once
 *  for the final picture.<br><br>
 * When editing the contents of a clip, all views must update to go to the specified clip. Since no camera layers exist
 * in clips, there cannot be any choices except maybe the "preview" option can stay. I am still deciding what exactly
 * should happen in situations like these.
 * 
 * @author Runouw
 *
 */
public class ViewPane extends JPanel {
	private static final long serialVersionUID = 1L;
	
	public ViewPreview view = null;
	
	private JPopupMenu buttonMenu;
	private JImageButton pickView;
	private Engine engine;
	
	private JLabel label;
	
	public ViewPane(Engine engine){
		super();
		this.engine = engine;
		
		this.setLayout(new BorderLayout());
		this.setMinimumSize(new Dimension(100, 100));
		
		try {
			view = new ViewPreview(engine, engine.sharedGL.gd, engine.sharedGL.pf, engine.sharedGL.sd);
			//engine.sharedGL.setDrawable(view);
		} catch (LWJGLException e) {
			e.printStackTrace();
		}
		
		this.add(view, BorderLayout.CENTER);
		
		JPanel bottom = new JPanel();
		this.add(bottom, BorderLayout.PAGE_END);
		
		bottom.setLayout(new BorderLayout());
		
		JPanel bottomLeft = new JPanel();
		bottom.add(bottomLeft, BorderLayout.LINE_START);
		bottomLeft.setLayout(new FlowLayout());
		
		JPanel bottomRight = new JPanel();
		bottom.add(bottomRight, BorderLayout.LINE_END);
		bottomRight.setLayout(new FlowLayout());
		
		label = new JLabel("");
		bottomLeft.add(label, BorderLayout.PAGE_END);
		
		buttonMenu = new JPopupMenu();
		
		reloadViewDropdown();
		
		pickView = new JImageButton(UIImages.popupGeneratorIcon);
		pickView.setPreferredSize(new Dimension(15, 15));
		pickView.setSize(new Dimension(15, 15));
		pickView.setToolTipText("Change view to...");
		
		pickView.addMouseListener(new MouseAdapter(){
			@Override
			public void mouseClicked(MouseEvent e) {
				reloadViewDropdown();
				buttonMenu.show(pickView, 0, pickView.getHeight());
			}
		});
		
		bottomRight.add(pickView);
	}
	private void reloadViewDropdown(){
		buttonMenu.removeAll();
		
		ArrayList<TimelineLayer> cameraLayers = engine.getListOfPossibleViews();
		
		int l = cameraLayers.size();
		for(int i=0;i<l;i++){
			TimelineLayer layer = cameraLayers.get(i);
			
			JMenuItem item = new JRadioButtonMenuItem(layer.name);
			item.addMouseListener(new ChangeViewFromDropDownButton(layer));
			
			boolean selected = false;
			if(view.getViewPath() != null){
				ViewNodeElement element = view.getViewPath().getRoot().element;
				if(element instanceof Element_Camera){
					Element_Camera camera = (Element_Camera) element;
					if(camera.getLayer() == layer){
						selected = true;
						
						label.setText(view.getViewPath().getPathString());
					}
				}
			}
			item.setSelected(selected);
			
			buttonMenu.add(item);
		}
		buttonMenu.addSeparator();
		JMenuItem preview = new JRadioButtonMenuItem("Preview");
		preview.addMouseListener(new ChangeViewFromDropDownButton(null));
		buttonMenu.add(preview);
		
		if(view.getViewPath() == null){
			preview.setSelected(true);
			
			label.setText("Preview");
			
		}else{
			preview.setSelected(false);
		}
		
		
	}
	class ChangeViewFromDropDownButton extends MouseAdapter{
		TimelineLayer layer;
		public ChangeViewFromDropDownButton(TimelineLayer layer){
			this.layer = layer;
		}
		@Override
		public void mouseReleased(MouseEvent e) {
			ViewPath path = null;
			if(layer == null){
				view.setViewPath(null);
				
				view.viewTransform = null;
			}else{
				path = new ViewPath();
				
				
				// TODO: make it choose the frame
				
				path.setRoot(new ViewNode(layer.getAsElement(0), 0));
				view.setViewPath(path);
				
				// TODO: maybe it could be nice to remember the last transformation per Camera....
				
				if(path.getDimension() == TransformDimension.THREE){
					//view.viewTransform.translate(0, 5, -100);
					Element_Camera elementCamera = (Element_Camera) layer.getAsElement(0);
					
					
					view.viewTransform = elementCamera.getViewTransform();
					
				}else{
					view.viewTransform = new ViewTransform();
					view.viewTransform.setTransform(new Transform(TransformDimension.TWO));
					
				}
				
			}
			
			if(path == null){
				label.setText("Preview");
			}else{
				label.setText(path.getPathString());
			}
			
			reloadViewDropdown();
			
			engine.setCurrentSelectedView(view);
			view.repaint();
			
			
		}
	}
	
	
}
